package com.security.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import com.security.domain.Resource;
import com.security.domain.Role;
import com.security.domain.User;
import com.utils.date.DateUtils;

/**
 * 实现SpringSecurity的UserDetailsService接口,获取用户Detail信息.
 * 
 * @author san
 */
public class UserDetailServiceImpl implements UserDetailsService {

	private UserService userService;

	public Operator loadUserByUsername(String userName)
			throws UsernameNotFoundException, DataAccessException {
		User user = userService.getUserByLoginName(userName);
		if (user == null) {
			throw new UsernameNotFoundException(userName + " 不存在 ");
		}
		GrantedAuthority[] grantedAuths = obtainGrantedAuthorities(user);

		//User类中无以下属性,暂时全部设为true.
		boolean enabled = true;
		boolean accountNonExpired = true;
		boolean credentialsNonExpired = true;
		boolean accountNonLocked = true;

		Operator operator = new Operator(user.getUsername(),
				user.getPassword(), enabled, accountNonExpired,
				credentialsNonExpired, accountNonLocked, grantedAuths);

		// 为Operator类加入登录时间信息.
		operator.setLoginTime(DateUtils.formatDate(new Date(), null));

		return operator;
	}

	/**
	 * 获得用户所有角色的权限.
	 */
	private GrantedAuthority[] obtainGrantedAuthorities(User user) {
		List<GrantedAuthority> authsList = new ArrayList<GrantedAuthority>();
		GrantedAuthority ag = null;
		for (Role role : user.getRoles()) {
			for (Resource res : role.getResources()) {
				ag = new GrantedAuthorityImpl(res.getName());
				authsList.add(ag);
				ag = null;
			}
		}
		return authsList.toArray(new GrantedAuthority[authsList.size()]);
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public UserService getUserService() {
		return userService;
	}
	
}
